﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace SlamCms.SharePoint.Core
{
	public class SharePointAction
	{
		protected SharePointItem SharePointItem
		{
			get;
			set;
		}

		public SharePointAction()
		{
			SharePointItem = new SharePointItem();
			SharePointItem.AccessWithElevatedPrivileges = false;
		}

		protected void Execute(Action method)
		{
			if (String.IsNullOrEmpty(SharePointItem.MonitoredScope))
			{
				ExecuteAction(method);
			}
			else
			{
				using (SPMonitoredScope monitoredScope = new SPMonitoredScope(SharePointItem.MonitoredScope))
				{
					ExecuteAction(method);
				}
			}
		}

		private void ExecuteAction(Action method)
		{
			if (SharePointItem.AccessWithElevatedPrivileges)
			{
				SPSecurity.RunWithElevatedPrivileges(delegate() { method.Invoke(); });
			}
			else
			{
				method.Invoke();
			}
		}

		public SharePointAction WithElevatedPrivileges()
		{
			SharePointItem.AccessWithElevatedPrivileges = true;
			return this;
		}

		public SharePointAction Monitor(string scope)
		{
			SharePointItem.MonitoredScope = scope;
			return this;
		}
	}

	public class SharePointAction<T> : SharePointAction where T : SharePointAction
	{
		public SharePointAction() :
			base()
		{	
		}

		public new T WithElevatedPrivileges()
		{
			SharePointItem.AccessWithElevatedPrivileges = true;
			return this as T;
		}

		public new T Monitor(string scope)
		{
			SharePointItem.MonitoredScope = scope;
			return this as T;
		}
	}
}
